﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.ComponentModel;

namespace IncomeOutcome.Model
{
    public class AppDataContext : DataContext
    {
        public AppDataContext(string connectionString)
            : base(connectionString)
        { }

        // Specify a table for the ItemValue.
        public Table<ItemValue> ItemValues;

        // Specify a table for the to-do items.
        public Table<Item> Items;
    }

    // ItemValue
    [Table]
    public class ItemValue : INotifyPropertyChanging, INotifyPropertyChanged
    {
        private int m_ItemValueId;
        [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
        public int ItemValueId
        {
            get { return m_ItemValueId; }
            set
            {
                if (m_ItemValueId != value)
                {
                    NotifyPropertyChanging("ItemValueId");
                    m_ItemValueId = value;
                    NotifyPropertyChanged("ItemValueId");
                }
            }
        }
        // NumberValue
        private double m_NumberValue;
        [Column]
        public double NumberValue
        {
            get { return m_NumberValue; }
            set
            {
                if (m_NumberValue != value)
                {
                    NotifyPropertyChanging("NumberValue");
                    m_NumberValue = value;
                    NotifyPropertyChanged("NumberValue");
                }
            }
        }
        // ValueOrder
        private int m_ValueOrder;
        [Column]
        public int ValueOrder
        {
            get { return m_ValueOrder; }
            set
            {
                if (m_ValueOrder != value)
                {
                    NotifyPropertyChanging("ValueOrder");
                    m_ValueOrder = value;
                    NotifyPropertyChanged("ValueOrder");
                }
            }
        }

        // Internal column for the associated Item ID value
        [Column]
        internal int m_ItemId;

        // Entity reference, to identify the Item "storage" table
        private EntityRef<Item> m_Item;

        // Association, to describe the relationship between this key and that "storage" table
        [Association(Storage = "m_Item", ThisKey = "m_ItemId", OtherKey = "ItemId", IsForeignKey = true)]
        public Item Item
        {
            get { return m_Item.Entity; }
            set
            {
                NotifyPropertyChanging("Item");
                m_Item.Entity = value;

                if (value != null)
                {
                    m_ItemId = value.ItemId;
                }

                NotifyPropertyChanging("Item");
            }
        }

        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        // Used to notify that a property changed
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

        #region INotifyPropertyChanging Members
        public event PropertyChangingEventHandler PropertyChanging;
        // Used to notify that a property is about to change
        private void NotifyPropertyChanging(string propertyName)
        {
            if (PropertyChanging != null)
            {
                PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
            }
        }
        #endregion
    }

    [Table]
    public class Item : INotifyPropertyChanging, INotifyPropertyChanged
    {
        public Item()
        {
            m_ItemValues = new EntitySet<ItemValue>(new Action<ItemValue>(attach_ItemValue), new Action<ItemValue>(detach_ItemValue));
        }
        // ItemId
        private int m_ItemId;
        [Column(DbType = "INT NOT NULL IDENTITY", IsDbGenerated = true, IsPrimaryKey = true)]
        public int ItemId
        {
            get { return m_ItemId; }
            set 
            {
                if (m_ItemId != value)
                {
                    NotifyPropertyChanging("ItemId");
                    m_ItemId = value;
                    NotifyPropertyChanged("ItemId");
                }
            }
        }
        // ItemName
        private string m_ItemName;
        [Column]
        public string ItemName
        {
            get { return m_ItemName; }
            set 
            {
                if (m_ItemName != value)
                {
                    NotifyPropertyChanging("ItemName");
                    m_ItemName = value;
                    NotifyPropertyChanged("ItemName");
                }
            }
        }
        // ImagePath
        private string m_ImagePath;
        [Column]
        public string ImagePath
        {
            get { return m_ImagePath; }
            set
            {
                if (m_ImagePath != value)
                {
                    NotifyPropertyChanging("ImagePath");
                    m_ImagePath = value;
                    NotifyPropertyChanged("ImagePath");
                }
            }
        }
        // PreviousItemId
        private int m_PreviousItemId;
        [Column]
        public int PreviousItemId
        {
            get { return m_PreviousItemId; }
            set
            {
                if (m_PreviousItemId != value)
                {
                    NotifyPropertyChanging("PreviousItemId");
                    m_PreviousItemId = value;
                    NotifyPropertyChanged("PreviousItemId");
                }
            }
        }
        // NextItemId
        private int m_NextItemId;
        [Column]
        public int NextItemId
        {
            get { return m_NextItemId; }
            set
            {
                if (m_NextItemId != value)
                {
                    NotifyPropertyChanging("NextItemId");
                    m_NextItemId = value;
                    NotifyPropertyChanged("NextItemId");
                }
            }
        }


        #region Not use
        //// PreviousItemId Internal column for the associated Item ID value
        //[Column(DbType = "INT NULL")]
        //internal int m_PreviousItemId;

        //// Entity reference, to identify the Item "storage" table
        //private EntityRef<Item> PreviousItemId;

        // //Association, to describe the relationship between this key and that "storage" table
        //[Association(Storage = "PreviousItemId", ThisKey = "m_PreviousItemId", OtherKey = "ItemId", IsForeignKey = true, DeleteOnNull = false)]
        ////[global::System.Data.Linq.Mapping.ColumnAttribute(Name = "m_PreviousItemId", Storage = "_M_PreviousItemId", DbType = "Int", UpdateCheck = UpdateCheck.Never)]
        //public Item PreviousItem
        //{
        //    get { return PreviousItemId.Entity; }
        //    set
        //    {
        //        NotifyPropertyChanging("Item");
        //        PreviousItemId.Entity = value;

        //        if (value != null)
        //        {
        //            m_PreviousItemId = value.m_PreviousItemId;
        //        }

        //        NotifyPropertyChanging("Item");
        //    }
        //}
        //// NextItemId Internal column for the associated Item ID value
        //[Column(DbType = "INT NULL")]
        //internal int m_NextItemId;

        //// Entity reference, to identify the Item "storage" table
        //private EntityRef<Item> NextItemId;

        //// Association, to describe the relationship between this key and that "storage" table
        //[Association(Storage = "NextItemId", ThisKey = "m_NextItemId", OtherKey = "ItemId", IsForeignKey = true, DeleteOnNull = false)]
        //public Item NextItem
        //{
        //    get { return NextItemId.Entity; }
        //    set
        //    {
        //        NotifyPropertyChanging("Item");
        //        NextItemId.Entity = value;

        //        if (value != null)
        //        {
        //            m_NextItemId = value.m_NextItemId;
        //        }

        //        NotifyPropertyChanging("Item");
        //    }
        //}
        #endregion Not use End

        // Define the entity set for the collection side of the relationship.
        private EntitySet<ItemValue> m_ItemValues;
        [Association(Storage = "m_ItemValues", OtherKey = "m_ItemId", ThisKey = "ItemId")]
        public EntitySet<ItemValue> ItemValues
        {
            get { return this.m_ItemValues; }
            set { this.m_ItemValues.Assign(value); }
        }

        // Called during an add operation
        private void attach_ItemValue(ItemValue pItemValue)
        {
            NotifyPropertyChanging("ItemValue");
            pItemValue.Item = this;
        }

        // Called during a remove operation
        private void detach_ItemValue(ItemValue pItemValue)
        {
            NotifyPropertyChanging("ItemValue");
            pItemValue.Item = null;
        }

        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        // Used to notify that a property changed
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

        #region INotifyPropertyChanging Members
        public event PropertyChangingEventHandler PropertyChanging;
        // Used to notify that a property is about to change
        private void NotifyPropertyChanging(string propertyName)
        {
            if (PropertyChanging != null)
            {
                PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
            }
        }
        #endregion
    }

}
